#pragma once

#include <iostream>
#include <unordered_map>
#include <memory>
#include <vector>
#include <chrono>
#include <filesystem>

#include "auxiliary.h"
#include "serialport.h"
#include "config.h"
#include "csvexporter.h"
#include "curlclient.h"

#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")

struct Record {
    std::chrono::system_clock::time_point last_updated;  // 上次更新时间
    std::string latest_data;                             // 最新数据值
};

class SensorCollection
{
private:
    LoadFile load;
    std::unordered_map<std::string, Serialnfo> serial_infos;
    std::string save_path;
    std::string timeout_url;
    
    std::vector<std::string> enable_sensor;
    std::unordered_map<std::string, std::unique_ptr<SerialPort>> serialports;
    std::unordered_map<std::string, std::unique_ptr<CSVExporter>> exporters;
    std::unordered_map<std::string, std::string> urls;

    // 传感器数据记录（核心：同时存储时间和值）
    std::unordered_map<std::string, Record> sensor_records;
    std::mutex records_mutex;  // 保护records的线程安全

    std::mutex enable_sensor_mutex;  // 保护 enable_sensor 的线程安全
    std::mutex urls_mutex;           // 保护 urls 的线程安全

    UINT m_timer_id{ 0 };  // 多媒体定时器ID

    int count { 0 }; 

    std::chrono::seconds timeout_threshold = std::chrono::seconds(2);
    const std::chrono::seconds check_interval = std::chrono::seconds(1);  // 默认1秒

    // 新增：超时检查线程和控制
    std::thread timeout_check_thread;          // 超时检查线程
    std::atomic<bool> stop_check_thread = false;  // 线程停止标志
    std::atomic<bool> is_timeout_thread_running = false;  // 新增：超时线程是否在运行
    std::mutex timeout_thread_mutex;  // 新增：保护线程启动/停止的互斥锁

    // 新增：给 Record 临时加告警标记（避免重复打印，无需修改结构体，用 unordered_map 单独存）
    std::unordered_map<std::string, bool> sensor_alerted;  // key：传感器名，value：是否已打印超时

public:

    SensorCollection();

    ~SensorCollection();

    void connect();

    void config_parameters(SerialPort *port, const std::string& name);

    // 1. 获取已连接的传感器列表
    std::vector<std::string> get_enabled_sensors() {
        std::lock_guard<std::mutex> lock(enable_sensor_mutex);
        return enable_sensor;
    }

    // 2. 判断定时器是否在运行
    bool is_timer_running() const {
        return m_timer_id != 0;  // m_timer_id 是原有定时器ID（0表示未运行）
    }

    std::string get_save_path() const{
        nlohmann::json j;
        j["data"] = { {"path", save_path}};
        return j;
    }

    void start_mm_timer(int intervalMs);  // 启动多媒体定时器

    void stop_mm_timer();                 // 停止多媒体定时器

    static void CALLBACK timer_proc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);  // 回调函数

    void read_sensor(const std::string& name, const std::chrono::system_clock::time_point& now);

    void transfer(const std::string& name);

    std::pair<std::string, std::string> mkfile(const std::string& name);

    std::string get_chrono_timestamp();

    static std::string trim_ws(const std::string& s);

    static std::string sanitize_for_filename(std::string s);

    void check_all_sensor_timeout();
};

